package org.wheel.plugins.starter.jdbc.pool.dao;

import cn.hutool.core.lang.Pair;
import org.wheel.module.core.entity.vo.Message;
import org.wheel.module.core.request.ApiParam;
import org.wheel.module.core.util.Page;
import org.wheel.plugins.toolkit.sql.core.LambdaDeleteWrapper;
import org.wheel.plugins.toolkit.sql.core.LambdaInsertWrapper;
import org.wheel.plugins.toolkit.sql.core.LambdaQueryWrapper;
import org.wheel.plugins.toolkit.sql.core.LambdaUpdateWrapper;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

public interface IBaseDao<T> {
    /** 统一加逻辑删除条件，无侵入 */
    public IBaseDao<T> applyLogicDelete(LambdaUpdateWrapper<T> wrapper, String opUserId);
    public IBaseDao<T> applyUpdateTime(LambdaUpdateWrapper<T> wrapper, String opUserId);

    public IBaseDao<T> applyInsertTime(LambdaInsertWrapper<T> wrapper, String opUserId);

    /* ===================== 通用 CRUD ===================== */

    /* ---------- 根据主键查询 ---------- */
    public Message selectByParam(LambdaQueryWrapper<T> wrapper, ApiParam apiParam);
    /**
     * 根据条件查询
     * @param wrapper 查询条件
     * @param apiParam 参数
     * @param targetClass 查询结果类型
     * @return 查询结果
     */
    public <E> Message selectByParam(LambdaQueryWrapper<T> wrapper, ApiParam apiParam, Class<E> targetClass);

    public T selectById(Serializable id);
    public <E> E selectById(Serializable id, Class<E> targetClass);
    /* ---------- 批量主键查询 ---------- */
    public List<T> selectBatchIds(Collection<? extends Serializable> ids);
    public <E> List<E> selectBatchIds(Collection<? extends Serializable> ids, Class<E> targetClass);
    /* ---------- 分页查询 ---------- */
    public <E> Page<E> selectPage(Page<E> page, LambdaQueryWrapper<T> wrapper, Class<E> targetClass);
    public Page<T> selectPage(Page<T> page, LambdaQueryWrapper<T> wrapper);

    /* ---------- 列表查询 ---------- */
    public List<T> selectListAll(LambdaQueryWrapper<T> wrapper);
    public <E> List<E> selectListAll(LambdaQueryWrapper<T> wrapper, Class<E> targetClass);
    public List<T> selectList(LambdaQueryWrapper<T> wrapper);
    public <E> List<E> selectList(LambdaQueryWrapper<T> wrapper, Class<E> targetClass);

    /* ---------- 单条查询 ---------- */
    public T selectOne(LambdaQueryWrapper<T> wrapper);
    public <E> E selectOne(LambdaQueryWrapper<T> wrapper, Class<E> targetClass);
    /* ---------- 计数 ---------- */
    public long selectCount(LambdaQueryWrapper<T> wrapper);

    /* ---------- 是否存在 ---------- */
    public boolean exists(LambdaQueryWrapper<T> wrapper);
    /* ---------- 插入 ---------- */
    public int insert(LambdaInsertWrapper<T> wrapper);
    public int insert(T entity);
    public int insert(T entity, String opUserId);
    /* ---------- 插入并返回主键 ---------- */
    public T insertAndGetId(T entity);

    public T insertAndGetId(T entity, String opUserId);

    /* ---------- 批量插入 ---------- */
    public int[] insertBatch(Collection<T> entities);
    public int[] insertBatch(Collection<T> entities, String opUserId);

    /* ---------- 根据主键更新 ---------- */
    public int update(LambdaUpdateWrapper<T> wrapper);
    /** 第二个参数值 ：是否忽略 null 值，true代表忽略，不更新对象中的null */
    public int updateById(T entity, String opUserId);
    public int updateById(T entity, boolean ignoreNull);
    public int updateById(T entity, boolean ignoreNull, String opUserId);
    /* ---------- 批量更新 ---------- */
    public int[] updateBatch(Collection<T> entities, boolean ignoreNull);
    public int[] updateBatch(Collection<T> entities, String opUserId);
    public int[] updateBatch(Collection<T> entities, boolean ignoreNull, String opUserId);

    public int[] updateBatch(Collection<Pair<T, Boolean>> entities);
    /** 默认第二个参数值null：忽略 null 值 */
    public int updateById(T entity);

    public int[] updateById(Collection<T> entities);
    /* ---------- 根据主键软删除 ---------- */
    public int logicRemoveById(Serializable id, String opUserId);

    public int deleteById(Serializable id);

    /* ---------- 条件软删除 ---------- */
    public int delete(LambdaDeleteWrapper<T> wrapper);
    public int logicRemove(LambdaUpdateWrapper<T> wrapper, String opUserId);
    /* ---------- 批量删除 ---------- */
    public int[] deleteBatchIds(Collection<? extends Serializable> ids);

    public int[] logicDeleteBatchIds(Collection<? extends Serializable> ids, String opUserId);

    public int[] delete(Collection<LambdaDeleteWrapper<T>> wrappers);

    public int[] logicDelete(Collection<LambdaUpdateWrapper<T>> wrappers, String opUserId);
}